<template>
  <div id="app-32-map" class="is-full"></div>
</template>

<script>
import Map3d from "@/utils/Map3d.js"
import TWEEN from "@tweenjs/tween.js"
import * as THREE from "three"
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js"
import { random } from "@/utils"
import useFileLoader from "@/hooks/useFileLoader.js"
import useCountry from "@/hooks/useCountry.js"
import useCoord from "@/hooks/useCoord.js"
import useConversionStandardData from "@/hooks/useConversionStandardData.js"
import useMapMarkedLightPillar from "@/hooks/map/useMapMarkedLightPillar"
import useSequenceFrameAnimate from "@/hooks/useSequenceFrameAnimate"
import useCSS2DRender from "@/hooks/useCSS2DRender"
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'; 

export default {
  props:{
    markers:{
      type:Array,
      default:()=>[],
      required:true
    }
  },
  data() {
    return {
      baseMap: null,
      rotatingApertureMesh: null,
      rotatingPointMesh: null,
      particleArr: [],
      css2dRender: null,
      textureMap: null,
      texturefxMap: null,
      topFaceMaterial: null,
      sideMaterial: null,
      bottomZ: -0.2,
      centerXY: { x: 113.429919, y: 23.334643 } ,
      css2dRenderer: null,
      markerObjects:[],
      lightPillars: [],
      isMapReady: false,
      pendingMarkers: [],
      hoveredMarker: null, // 当前悬停的marker
      raycaster: new THREE.Raycaster(), // 用于射线检测
      mouse: new THREE.Vector2(), // 鼠标位置
      hoverLabel: null,
      mouseMoveHandler: null,
      mouseOutHandler: null,
    }
  },
    mounted() {
      this.initMap()
      window.addEventListener("resize", this.resize)
    },
    beforeDestroy() {
    // 取消动画循环
    if (this.baseMap?.animationStop) {
      cancelAnimationFrame(this.baseMap.animationStop);
    }
    
    // 移除所有事件监听器
    window.removeEventListener("resize", this.resize);
    const rendererDom = this.baseMap?.renderer?.domElement;
    if (rendererDom) {
      if (this.mouseMoveHandler) {
        rendererDom.removeEventListener('mousemove', this.mouseMoveHandler);
      }
      if (this.mouseOutHandler) {
        rendererDom.removeEventListener('mouseout', this.mouseOutHandler);
      }
    }
    
    // 清理Three.js资源
    this.cleanupThreeResources();
    
    // 清理CSS2D渲染器
    if (this.css2dRenderer) {
      this.css2dRenderer.domElement.remove();
      this.css2dRenderer = null;
    }
    
    // 清理所有引用
    this.baseMap = null;
    this.raycaster = null;
    this.mouse = null;
  },
  watch: {
    markers: {
      deep: true,
      immediate: true,
      handler(newMarkers) {
        const validMarkers = newMarkers.filter(marker => 
        marker && !isNaN(parseFloat(marker.lng)) && !isNaN(parseFloat(marker.lat)))
      
        if (this.isMapReady && this.baseMap) {
          this.updateMarkers(validMarkers);
        } else {
          // 存储有效的markers等待地图初始化完成
          this.pendingMarkers = validMarkers;
        }
      }
    }
  },
  methods: {
    cleanupThreeResources() {
      // 清理场景
      if (this.baseMap?.scene) {
        // 移除所有子对象
        while(this.baseMap.scene.children.length > 0) {
          const obj = this.baseMap.scene.children[0];
          this.baseMap.scene.remove(obj);
          
          // 递归清理对象
          this.disposeObject(obj);
        }
      }
      
      // 清理渲染器
      if (this.baseMap?.renderer) {
        this.baseMap.renderer.dispose();
        this.baseMap.renderer.forceContextLoss();
        this.baseMap.renderer.domElement = null;
      }
      
      // 清理其他Three.js资源
      [this.textureMap, this.texturefxMap, this.topFaceMaterial, this.sideMaterial].forEach(resource => {
        if (resource) resource.dispose();
      });
      
      // 清理几何体和材质
      [this.rotatingApertureMesh, this.rotatingPointMesh].forEach(mesh => {
        if (mesh) {
          if (mesh.geometry) mesh.geometry.dispose();
          if (mesh.material) {
            if (Array.isArray(mesh.material)) {
              mesh.material.forEach(m => m.dispose());
            } else {
              mesh.material.dispose();
            }
          }
        }
      });
      
      // 清理标记和光柱
      this.clearMarkers();
    },
    disposeObject(obj) {
      if (!obj) return;
      
      // 清理几何体和材质
      if (obj.geometry) obj.geometry.dispose();
      if (obj.material) {
        if (Array.isArray(obj.material)) {
          obj.material.forEach(m => m.dispose());
        } else {
          obj.material.dispose();
        }
      }
      
      // 递归清理子对象
      if (obj.children) {
        obj.children.forEach(child => this.disposeObject(child));
      }
      
      // 清理CSS2D对象
      if (obj instanceof CSS2DObject && obj.element) {
        obj.element.remove();
      }
    },
    // 初始化鼠标事件
    initMouseEvents() {
      const rendererDom = this.baseMap.renderer.domElement;
      
      this.mouseMoveHandler = (event) => {
        this.mouse.x = (event.clientX / rendererDom.clientWidth) * 2 - 1;
        this.mouse.y = -(event.clientY / rendererDom.clientHeight) * 2 + 1;
        this.checkMarkerHover();
      };
      
      this.mouseOutHandler = () => {
        this.clearHoverEffect();
      };

      rendererDom.addEventListener('mousemove', this.mouseMoveHandler);
      rendererDom.addEventListener('mouseout', this.mouseOutHandler);
    },

    // 检查鼠标是否悬停在marker上
    checkMarkerHover() {
      if (!this.baseMap || !this.lightPillars.length) return;

      this.raycaster.setFromCamera(this.mouse, this.baseMap.camera);
      
       // 1. 检测光柱交点
      let intersects = [];
      if (this.lightPillars.length > 0) {
        intersects = this.raycaster.intersectObjects(
          this.lightPillars.flatMap(pillar => pillar.children),
          true
        );
      }

      // 2. 检测标签交点
      const labelIndex = this.checkLabelIntersection(this.mouse);

      if (intersects.length > 0) {
      const intersected = intersects[0];
      const pillar = intersected.object.parent;
      const markerIndex = this.lightPillars.indexOf(pillar);
      if (markerIndex !== -1) {
        this.handleMarkerHover(markerIndex);
        return;
      }
    }

      if (labelIndex !== -1) {
      this.handleMarkerHover(labelIndex);
      return;
    }

      this.clearHoverEffect();
    },

    checkLabelIntersection(mousePos) {
      // 由于CSS2D标签不是Three.js对象，需要用DOM方式检测
      const elements = document.querySelectorAll('.map-marker-label');
      const mouseX = (mousePos.x + 1) / 2 * window.innerWidth;
      const mouseY = (-mousePos.y + 1) / 2 * window.innerHeight;
      
      for (let i = 0; i < elements.length; i++) {
        const rect = elements[i].getBoundingClientRect();
        if (
          mouseX >= rect.left && 
          mouseX <= rect.right && 
          mouseY >= rect.top && 
          mouseY <= rect.bottom
        ) {
         return parseInt(elements[i].getAttribute('data-index'));
        }
      }
      return -1;
    },

    // 处理marker悬停
    handleMarkerHover(markerIndex) {
      if (this.hoveredMarker === markerIndex) return;

      // 清除之前的效果
      this.clearHoverEffect();
      
      // 设置当前悬停的marker
      this.hoveredMarker = markerIndex;
      
      // 高亮效果
      const pillar = this.lightPillars[markerIndex];
      pillar.scale.set(1.5, 1.5, 1.5);
      
      // 创建悬停标签
      const marker = this.markers[markerIndex];
      this.createHoverLabel(marker);
    },

    createHoverLabel(marker) {
      // 确保清除旧标签
      this.clearExistingLabel()

      // 创建带样式的HTML内容
      const htmlContent = `
        <div>
          <div class="station-info">
            <h3>${marker.name || '未命名电站'}</h3>
            <div class="image-container">
              ${marker.img ? `<img src="${marker.img}" alt="${marker.name}">` : '<div class="no-image">暂无图片</div>'}
            </div>
            <div class="details">
              <p><span>库容：</span>${marker.reservoirCapacity || '--'}</p>
              <p><span>坝型：</span>${marker.damCategory || '--'}</p>
              <p><span>坝高：</span>${marker.damHeight || '--'}</p>
              <p><span>装机容量：</span>${marker.installation || '--'}</p>
              <p><span>投产时间：</span>${marker.productionTime || '--'}</p>
              <p><span>状态：</span>${marker.status || '--'}</p>
            </div>
          </div>
        </div>
      `;

      
this.hoverLabel = new CSS2DObject(this.createLabelElement(htmlContent));
  
  this.hoverLabel.position.set(
    marker.lng,
    marker.lat,
    5.0
  );

  // 5. 仅添加到CSS2DRenderer
  if (this.baseMap?.css2dRenderer) {

    this.baseMap.scene.add(this.hoverLabel);
    this.forceRender();
  } else {
    console.error("CSS2DRenderer is not initialized!");
  }

  // 6. 强制渲染
  this.forceRender();
     
        },
    createLabelElement(html) {
      const div = document.createElement('div');
      div.className = 'map-hover-label';
      div.innerHTML = html;
      return div;
    },
    clearExistingLabel() {
        if (!this.hoverLabel) return;
        
        
        // 从CSS2DRenderer移除
        if (this.baseMap?.css2dRenderer?.domElement?.contains(this.hoverLabel.element)) {
          this.baseMap.css2dRenderer.domElement.removeChild(this.hoverLabel.element);
        }
        
        // 从Three.js场景移除
        if (this.baseMap?.scene) {
          this.baseMap.scene.remove(this.hoverLabel);
        }
        
        // 销毁元素
        if (this.hoverLabel.element) {
          this.hoverLabel.element.remove();
        }

        this.hoverLabel = null;
      },

        forceRender() {
      if (!this.baseMap) return;

      requestAnimationFrame(() => {
        this.baseMap.renderer.render(this.baseMap.scene, this.baseMap.camera);
        if (this.baseMap.css2dRenderer) {
          this.baseMap.css2dRenderer.render(this.baseMap.scene, this.baseMap.camera);
        }
      });
    },
    // 清除悬停效果
    clearHoverEffect() {
      if (this.hoveredMarker !== null) {
        const pillar = this.lightPillars[this.hoveredMarker];
        if (pillar) pillar.scale.set(1, 1, 1);
        this.hoveredMarker = null;
      }
      
      if (this.hoverLabel) {
        this.baseMap.scene.remove(this.hoverLabel);
        this.hoverLabel = null;
      }
    },
    resize() {
      if (this.baseMap) {
        this.baseMap.resize()
      }
    },
    clearMarkers() {
      // 清除光柱
      this.lightPillars.forEach(pillar => {
        this.disposeObject(pillar);
        if (this.baseMap?.scene) {
          this.baseMap.scene.remove(pillar);
        }
      });
      this.lightPillars = [];
      
      // 清除标签
      this.markerObjects.forEach(obj => {
        if (obj.label) {
          this.disposeObject(obj.label);
        }
      });
      this.markerObjects = [];
      
      // 清除悬停状态
      this.clearHoverEffect();
    },
    updateMarkers(markers) {
       console.log('Updating markers:', markers);
      this.clearMarkers();

      if (!markers || markers.length === 0) return;

      markers.forEach((marker,index) => {
        const label = this.create2DTag(marker.name, "map-marker-label");
        label.show(
          marker.name,
          new THREE.Vector3(marker.lng, marker.lat,1)
        );
        label.element.setAttribute('data-index', index);
        this.baseMap.scene.add(label);


        // 创建光柱效果
        const { createLightPillar } = useMapMarkedLightPillar({
          scaleFactor:2.4,
        });
        let heightScaleFactor = 0.4 + random(1, 5) / 3;
        let light = createLightPillar(marker.lng, marker.lat, heightScaleFactor);
        light.position.z = 0.31;
        // 为光柱添加自定义属性，便于识别
        light.userData = { markerIndex: index };

        this.baseMap.scene.add(light);
        this.lightPillars.push(light);

        this.markerObjects.push({ label });

        // 初始化鼠标事件（只在第一次更新markers时）
        if (!this._mouseEventsInitialized) {
          this.initMouseEvents();
          this._mouseEventsInitialized = true;
        }
      });
    },
    initGui() {
      const gui = new GUI()
      const guiParams = {
        topColor: "#002850",
        sideColor: "#123024",
        scale: 0.1,
      }
      gui.addColor(guiParams, "topColor").onChange((val) => {
        this.topFaceMaterial.color = new THREE.Color(val)
      })
      gui.addColor(guiParams, "sideColor").onChange((val) => {
        this.sideMaterial.color = new THREE.Color(val)
      })
      gui.add(guiParams, "scale", 0, 1).onChange((val) => {
        this.textureMap.repeat.set(val, val)
        this.texturefxMap.repeat.set(val, val)
      })
    },
    initRotatingAperture(scene, width) {
      const texture = new THREE.TextureLoader().load("/data/map/rotatingAperture.png")
      const plane = new THREE.PlaneBufferGeometry(width, width)
      const material = new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true,
        opacity: 1,
        depthTest: true,
      })
      const mesh = new THREE.Mesh(plane, material)
      mesh.position.set(this.centerXY.x, this.centerXY.y, 0) 
      mesh.scale.set(1.1, 1.1, 1.1)
      scene.add(mesh)
      this.rotatingApertureMesh = mesh
      return mesh
    },
    initRotatingPoint(scene, width) {
      const texture = new THREE.TextureLoader().load("/data/map/rotating-point2.png")
      const plane = new THREE.PlaneBufferGeometry(width, width)
      const material = new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true,
        opacity: 1,
        depthTest: true,
      })
      const mesh = new THREE.Mesh(plane, material)
      mesh.position.set(this.centerXY.x, this.centerXY.y, this.bottomZ - 0.02)
      mesh.scale.set(0.8, 0.8,0.8)
      scene.add(mesh)
      this.rotatingPointMesh = mesh
      return mesh
    },
    initSceneBg(scene, width) {
      const texture = new THREE.TextureLoader().load("/data/map/scene-bg2.png")
      const plane = new THREE.PlaneBufferGeometry(width * 4, width * 4)
      const material = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        map: texture,
        transparent: true,
        opacity: 1,
        depthTest: true,
      })
      const mesh = new THREE.Mesh(plane, material)
      mesh.position.set(this.centerXY.x, this.centerXY.y, this.bottomZ - 0.2)
      scene.add(mesh)
    },
    initCirclePoint(scene, width) {
      const texture = new THREE.TextureLoader().load("/data/map/circle-point.png")
      const plane = new THREE.PlaneBufferGeometry(width, width)
      const material = new THREE.MeshPhongMaterial({
        color: 0x00ffff,
        map: texture,
        transparent: true,
        opacity: 1,
      })
      const mesh = new THREE.Mesh(plane, material)
      mesh.position.set(this.centerXY.x, this.centerXY.y, this.bottomZ - 0.1)
      scene.add(mesh)
    },
    initBorderLine(data, mapGroup) {
      const { createCountryFlatLine } = useCountry()
      let lineTop = createCountryFlatLine(
        data,
        {
          color: 0xffffff,
          linewidth: 0.0015,
          transparent: true,
          depthTest: false,
        },
        "Line2"
      )
      lineTop.position.z += 0.305
      let lineBottom = createCountryFlatLine(
        data,
        {
          color: 0x61fbfd,
          linewidth: 0.002,
          depthTest: false,
        },
        "Line2"
      )
      lineBottom.position.z -= 0.1905
      mapGroup.add(lineTop)
      mapGroup.add(lineBottom)
    },
    initLightPoint(properties, mapGroup) {
      if (!properties.centroid && !properties.center) {
        return false
      }
      const { createLightPillar } = useMapMarkedLightPillar({
        scaleFactor: 3,
      })
      let heightScaleFactor = 0.4 + random(1, 10) / 5
      let lightCenter = properties.centroid || properties.center
      let light = createLightPillar(...lightCenter, heightScaleFactor)
      light.position.z = 0.31
      mapGroup.add(light)
    },
    initLabel(properties, scene) {
      if (!properties.name) {
        console.warn('Missing name property', properties)
        return
      }
      
      if (!this.css2dRenderer) {
        console.error('CSS2DRenderer not initialized!')
        return
      }

      const label = this.create2DTag(properties.name, "map-32-label")
      
      // 获取坐标（优先使用center，没有则使用centroid）
      const coords = properties.center || properties.centroid
      if (!coords) {
        console.error('No coordinates for label', properties)
        return
      }

      // 显示标签
      label.show(
        properties.name, 
        new THREE.Vector3(
          coords[0] || coords.x,
          coords[1] || coords.y,
          0.5  
        )
      )

      // 添加到场景
      scene.add(label)
    },
    async initMap() {
      this.isMapReady = false;
      this.pendingMarkers = [...this.markers];

      const { requestData } = useFileLoader()
      const { transfromGeoJSON } = useConversionStandardData()
      const { getBoundingBox } = useCoord()
      const { initCSS2DRender, create2DTag } = useCSS2DRender()

      this.css2dRenderer = initCSS2DRender(
        { width: window.innerWidth, height: window.innerHeight },
        document.getElementById('app-32-map')
      )
      this.create2DTag = create2DTag
      const texture = new THREE.TextureLoader()
      this.textureMap = texture.load("/data/map/gz-map.jpg")
      this.texturefxMap = texture.load("/data/map/gz-map-fx.jpg")
      this.textureMap.wrapS = this.texturefxMap.wrapS = THREE.RepeatWrapping
      this.textureMap.wrapT = this.texturefxMap.wrapT = THREE.RepeatWrapping
      this.textureMap.flipY = this.texturefxMap.flipY = false
      this.textureMap.rotation = this.texturefxMap.rotation = THREE.MathUtils.degToRad(45)
      const scale = 0.128
      this.textureMap.repeat.set(scale, scale)
      this.texturefxMap.repeat.set(scale, scale)

      this.topFaceMaterial = new THREE.MeshPhongMaterial({
        map: this.textureMap,
        color: 0x002850,
        combine: THREE.MultiplyOperation,
        transparent: true,
        opacity: 1,
      })
      this.sideMaterial = new THREE.MeshLambertMaterial({
        color: 0x123024,
        transparent: true,
        opacity: 0.9,
      })

      let provinceData = await requestData("./data/map/china.json")
      provinceData = transfromGeoJSON(provinceData)

      const self = this 

      class CurrentMap3d extends Map3d {
        constructor(props) {
          super({
            ...props,
            statsVisibel: false, 
          });
        }
        initCamera() {
          let { width, height } = this.options
          let rate = width / height
          this.camera = new THREE.PerspectiveCamera(45, rate, 0.1, 1000)
          this.camera.up.set(0, 0, 1)
          this.camera.position.set(106, 10, 20)         
          this.camera.lookAt(self.centerXY.x, self.centerXY.y, 0) 
        }
        initModel() {
          try {
            this.mapGroup = new THREE.Group()
           this.css2dRenderer = initCSS2DRender(this.options, this.container)

            provinceData.features.forEach((elem) => {
              const province = new THREE.Object3D()
              const coordinates = elem.geometry.coordinates
              const properties = elem.properties

              coordinates.forEach((multiPolygon) => {
                multiPolygon.forEach((polygon) => {
                  const shape = new THREE.Shape()
                  for (let i = 0; i < polygon.length; i++) {
                    let [x, y] = polygon[i]
                    if (i === 0) {
                      shape.moveTo(x, y)
                    }
                    shape.lineTo(x, y)
                  }
                  const extrudeSettings = {
                    depth: 0.2,
                    bevelEnabled: true,
                    bevelSegments: 1,
                    bevelThickness: 0.1,
                  }
                  const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
                  const mesh = new THREE.Mesh(geometry, [
                    self.topFaceMaterial,
                    self.sideMaterial
                  ])
                  province.add(mesh)
                })
              })
              this.mapGroup.add(province)

              self.initLabel(properties, this.scene)
            })

            self.initBorderLine(provinceData, this.mapGroup)

            let earthGroupBound = getBoundingBox(this.mapGroup)
            self.centerXY = { x: earthGroupBound.center.x, y: earthGroupBound.center.y } // 更新中心点
            let { size } = earthGroupBound
            let width = size.x < size.y ? size.y + 1 : size.x + 1

            // self.initRotatingAperture(this.scene, width)
            // self.initRotatingPoint(this.scene, width)
            self.initCirclePoint(this.scene, width)
            self.initSceneBg(this.scene, width)

            this.scene.add(this.mapGroup)
            self.isMapReady = true;
           // 检查是否有待处理的markers
            if (self.pendingMarkers.length > 0) {
              self.updateMarkers(self.pendingMarkers);
              self.pendingMarkers = [];
            }
            self.initGui()

            self.raycaster = new THREE.Raycaster();
          self.mouse = new THREE.Vector2();
          } catch (error) {
            console.log(error)
          }
        }
        initControls() {
          super.initControls()
          this.controls.target = new THREE.Vector3(
            self.centerXY.x, 
            self.centerXY.y + 6, 
            0
          )
        }
        initLight() {
          let directionalLight1 = new THREE.DirectionalLight(0x7af4ff, 1)
          directionalLight1.position.set(self.centerXY.x, self.centerXY.y, 30)
          let directionalLight2 = new THREE.DirectionalLight(0x7af4ff, 1)
          directionalLight2.position.set(self.centerXY.x, self.centerXY.y, 30)
          let ambientLight = new THREE.AmbientLight(0x7af4ff, 1)
          this.addObject(directionalLight1)
          this.addObject(directionalLight2)
          this.addObject(ambientLight)
        }
        initRenderer() {
          super.initRenderer()
          this.renderer.outputEncoding = THREE.sRGBEncoding
        }
        loop() {
          this.animationStop = window.requestAnimationFrame(() => {
            this.loop()
          })
          // 必须首先渲染3D场景
          this.renderer.render(this.scene, this.camera)
          
          // 然后渲染2D标签
          if (this.css2dRenderer) {
            this.css2dRenderer.render(this.scene, this.camera)
          }
          if (this.options.controls.visibel && this.controls) {
            this.controls.update()
          }
          if (this.options.statsVisibel) this.stats.update()
          if (self.rotatingApertureMesh) {
            self.rotatingApertureMesh.rotation.z += 0.0005
          }
          if (self.rotatingPointMesh) {
            self.rotatingPointMesh.rotation.z -= 0.0005
          }
          if (this.css2dRender) {
            this.css2dRender.render(this.scene, this.camera)
          }
          TWEEN.update()
        }
        resize() {
          super.resize()
          this.renderer.render(this.scene, this.camera)
          this.renderer.setPixelRatio(window.devicePixelRatio)
          if (this.css2dRender) {
            this.css2dRender.setSize(this.options.width, this.options.height)
          }
        }
      }

      this.baseMap = new CurrentMap3d({
        container: "#app-32-map",
        axesVisibel: true,
        controls: {
          enableDamping: true,
          maxPolarAngle: (Math.PI / 2) * 0.98,
        },
      })

      this.baseMap.onLoad = () => {
        this.isMapReady = true;
        if (this.pendingMarkers.length > 0) {
          this.updateMarkers(this.pendingMarkers);
          this.pendingMarkers = [];
        }
      };
      this.baseMap.run()
    },
  },
}
</script>

<style>
html,
body,
#app,
.is-full {
  width: 100%;
  height: 100%;
  overflow: hidden;

}
.map-32-label {
  font-size: 10px;
  color: #fff;
}
.map-marker-label{
  font-size: 12px;
  color: #fff;
  background: rgba(0, 0, 0, 0.7);
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  transform: translateX(-50%) translateY(-100%);
  text-shadow: 0 0 3px #000;
}

/* 基础样式 */
.map-hover-label {
  position: absolute;
  background: rgba(0, 40, 80, 0.95);
  border: 1px solid #1a8cff;
  border-radius: 8px;
  padding: 15px;
  width: 400px;
  color: white;
  font-size: 14px;
  box-shadow: 0 0 20px rgba(26, 140, 255, 0.6);
  transform: translateX(-50%) translateY(-100%);
  pointer-events: none;
  z-index: 10000; /* 确保在最顶层 */
}

/* 内容样式 */
.map-hover-label h3 {
  margin: 0 0 10px 0;
  color: #1a8cff;
  font-size: 18px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  padding-bottom: 8px;
}

.map-hover-label .image-container {
  margin: 10px 0;
  text-align: center;
}

.map-hover-label img {
  width: 100%;

  border-radius: 4px;
}

.map-hover-label .no-image {
  padding: 30px;
  background: rgba(0,0,0,0.2);
  text-align: center;
  color: #aaa;
}

.map-hover-label .details p {
  margin: 5px 0;
  display: flex;
  color: #ffffff !important; /* 强制文字白色 */
}

.map-hover-label .details span {
  color: #a0d1ff;
  min-width: 80px;
  display: inline-block;
   color: inherit !important; /* 子元素继承颜色 */
}
.map-hover-label {
  font-size: 14px !important; /* 确保字体大小有效 */
  overflow: visible !important; /* 禁止裁剪 */
  white-space: normal !important; /* 允许换行 */
   z-index: 9999 !important; /* 确保在最顶层 */
  position: relative !important; /* 重置定位 */
  overflow: visible !important;
}
</style>